package com.whsxt.config;

import cn.hutool.core.io.FileUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @Author: caoqingwen
 * @CreateTime: 2021-03-12 10:36
 * @Description: 资源解析（JWT）
 * <p>
 * 统一做jwt的解析
 */
@Configuration
@EnableResourceServer           //开启资源服务器
@EnableGlobalMethodSecurity(prePostEnabled = true)     //开启方法级别的验证
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {


    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     * 做公钥的解析
     *
     * @return
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        //设置公钥
        ClassPathResource resource = new ClassPathResource("publicKey.txt");

        String publicKey = null;
        try {
//            InputStream inputStream = resource.getInputStream();
//            publicKey = FileUtil.readString(inputStream.readAllBytes(), Charset.defaultCharset());
            publicKey = StreamUtils.copyToString(
                    resource.getInputStream(),
                    StandardCharsets.UTF_8
            );
            jwtAccessTokenConverter.setVerifierKey(publicKey);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //jwtAccessTokenConverter.setVerifierKey(publicKey);
        return jwtAccessTokenConverter;
    }

    /**
     * 设置资源
     *
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.tokenStore(tokenStore());
    }


    /**
     * 配置放行的路径,所有的微服务都依赖common，其他微服务就不用再配了
     *
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        //因为使用jwt的方式，session就不需要了
        http.sessionManagement().disable();

        http.authorizeRequests().antMatchers(
//                "/v2/api-docs",
//                "/v3/api-docs",
//                "/swagger-resources/configuration/ui", //用来获取支持的动作
//                "/swagger-resources", //用来获取 api-docs 的 URI "/swagger-resources/configuration/security",//安全选项
//                "/webjars/**",
//                "/swagger-ui/**",
//                "/druid/**",
//                "/actuator/**",
//                "/payNotify/**"     //支付宝回调接口，放行
                "/**"
        ).permitAll()
                .antMatchers("/**")
                .authenticated()
                .and()
                .headers()
                .cacheControl();    //控制请求头的缓存
    }
}
